package se.statifyme.server;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import se.statifyme.shared.StringUtils;

public class FilterMatcher {
	
	public enum Matcher {
		CONTAINS {
			@Override
			public boolean isMatch(String pattern, String test) {
				return test.contains(pattern);
			}
		},
		EQUALS {
			@Override
			public boolean isMatch(String pattern, String test) {
				return test.equals(pattern);
			}
		},
		EQUALS_IGNORE_CASE {
			@Override
			public boolean isMatch(String pattern, String test) {
				return test.equalsIgnoreCase(pattern);
			}
		},
		ENDS_WITH {
			@Override
			public boolean isMatch(String pattern, String test) {
				return test.endsWith(pattern);
			}
		},
		STARTS_WITH {
			@Override
			public boolean isMatch(String pattern, String test) {
				return test.startsWith(pattern);
			}
		},
		REGEXP {
			@Override
			public boolean isMatch(String pattern, String test) {
				return test.matches(pattern);
			}
		};
		
		public abstract boolean isMatch(String pattern, String test);
	}

	private final Matcher matcher;
	private final Set<String> patterns;

	public FilterMatcher(Matcher matcher) {
		if (matcher == null) {
			throw new IllegalArgumentException("Matcher must not be null");
		}
		this.matcher = matcher;
		patterns = new HashSet<String>();
	}
	
	public void addFilterPattern(String pattern) {
		add(pattern);
	}

	/**
	 * Adds a comma separated list of filters.
	 * 
	 * @param filterPatterns The filter patterns.
	 */
	public void addFilterPatterns(String patterns) {
		if (StringUtils.isNotBlank(patterns)) {
			final String[] split = patterns.split(",");
			for (String url : split) {
				add(url);
			}
		}
	}

	public void addFilterPatterns(Collection<String> patterns) {
		for (String pattern : patterns) {
			add(pattern);
		}
	}

	public boolean isMatch(String test) {
		for (String pattern : patterns) {
			if (matcher.isMatch(pattern, test)) {
				return true;
			}
		}
		return false;
	}

	private void add(String pattern) {
		this.patterns.add(pattern.trim());
	}

}
